using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using Oracle.ManagedDataAccess.Types;

namespace OracleInternal.ServiceObjects
{
	internal class DotNetXmlImpl
	{
		internal static string ConvertXmlReaderToString(XmlReader reader)
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.PreserveWhitespace = true;
			xmlDocument.Load(reader);
			return xmlDocument.OuterXml;
		}

		internal static string ConvertXmlDocToString(XmlDocument xmlDoc)
		{
			return xmlDoc.OuterXml;
		}

		internal static string GetRootElement(XmlDocument xmlDoc)
		{
			return xmlDoc.DocumentElement.Name;
		}

		internal static string Extract(XmlDocument xmlDoc, string xpathExpr, string nsMap)
		{
			XmlNamespaceManager nsMgr = StringToNsMgr(xmlDoc.NameTable, nsMap);
			return Extract(xmlDoc, xpathExpr, nsMgr);
		}

		internal static string Extract(XmlDocument xmlDoc, string xpathExpr, XmlNamespaceManager nsMgr)
		{
			XmlNode xmlNode = null;
			xmlNode = xmlDoc.SelectSingleNode(xpathExpr, nsMgr);
			if (xmlNode != null)
			{
				if (xmlNode.NodeType == XmlNodeType.Attribute)
				{
					return xmlNode.Value;
				}
				string text = xmlNode.OuterXml;
				XmlNode nextSibling = xmlNode.NextSibling;
				if (nextSibling is XmlWhitespace)
				{
					text += nextSibling.OuterXml;
				}
				return text;
			}
			return string.Empty;
		}

		internal static bool IsExists(XmlDocument xmlDoc, string xpathExpr, XmlNamespaceManager nsMgr)
		{
			bool flag = false;
			try
			{
				return xmlDoc.SelectSingleNode(xpathExpr, nsMgr) != null;
			}
			catch (Exception)
			{
				return false;
			}
		}

		internal static bool IsExists(XmlDocument xmlDoc, string xpathExpr, string nsMap)
		{
			XmlNamespaceManager nsMgr = StringToNsMgr(xmlDoc.NameTable, nsMap);
			return IsExists(xmlDoc, xpathExpr, nsMgr);
		}

		internal static string Transform(XmlReader xslReader, XmlDocument xmlDoc, string paramMap)
		{
			using StringWriter stringWriter = new StringWriter();
			using XmlWriter results = XmlWriter.Create(stringWriter, new XmlWriterSettings
			{
				OmitXmlDeclaration = true,
				ConformanceLevel = ConformanceLevel.Auto
			});
			XslCompiledTransform xslCompiledTransform = new XslCompiledTransform();
			xslCompiledTransform.Load(xslReader);
			xslCompiledTransform.Transform(xmlDoc.CreateNavigator(), null, results);
			return stringWriter.ToString();
		}

		internal static string Transform(OracleXmlType xslDoc, XmlDocument xmlDoc, string paramMap)
		{
			return Transform(xslDoc.GetXmlReader(), xmlDoc, paramMap);
		}

		internal static string Transform(string xslDoc, XmlDocument xmlDoc, string paramMap)
		{
			return Transform(new XmlTextReader(new StringReader(xslDoc)), xmlDoc, paramMap);
		}

		internal static void Update(XmlDocument xmlDoc, string xpathExpr, XmlNamespaceManager nsMgr, string val, ref bool bValueIsFragment)
		{
			if (string.IsNullOrEmpty(val))
			{
				XmlNodeList xmlNodeList = xmlDoc.SelectNodes(xpathExpr, nsMgr);
				for (int num = xmlNodeList.Count - 1; num > -1; num--)
				{
					xmlNodeList[num].ParentNode.RemoveChild(xmlNodeList[num]);
				}
				if (bValueIsFragment && xmlDoc.FirstChild.ChildNodes.Count == 1)
				{
					XmlNode newChild = xmlDoc.DocumentElement.ChildNodes[0];
					xmlDoc.RemoveChild(xmlDoc.DocumentElement);
					xmlDoc.AppendChild(newChild);
					bValueIsFragment = false;
				}
				return;
			}
			XPathNodeIterator xPathNodeIterator;
			try
			{
				xPathNodeIterator = xmlDoc.CreateNavigator().Select(xpathExpr, nsMgr);
			}
			catch (Exception)
			{
				return;
			}
			bool flag = false;
			if (!bValueIsFragment && xpathExpr.StartsWith("/"))
			{
				if (xpathExpr.Length > 2)
				{
					if (xpathExpr.IndexOf("/", 2) == -1)
					{
						flag = true;
					}
				}
				else
				{
					flag = true;
				}
			}
			if (xPathNodeIterator == null || xPathNodeIterator.Count <= 0)
			{
				return;
			}
			int num2 = xPathNodeIterator.Count;
			IEnumerator enumerator = xPathNodeIterator.GetEnumerator();
			enumerator.MoveNext();
			XPathNavigator xPathNavigator = (XPathNavigator)enumerator.Current;
			string name = xPathNavigator.Name;
			XPathNavigator xPathNavigator2 = null;
			while (num2 > 0)
			{
				if (xPathNavigator.Name == name)
				{
					XmlDocumentFragment xmlDocFragmentInternal;
					if (xPathNavigator.NodeType == XPathNodeType.Root || (xPathNavigator.Name == xmlDoc.DocumentElement.Name && flag))
					{
						XmlDocument xmlDocument;
						try
						{
							xmlDocument = GetXmlDocument(new XmlTypeReader(new StringReader(val)), val, out xmlDocFragmentInternal, out bValueIsFragment, bThrowException: false);
						}
						catch (Exception)
						{
							return;
						}
						XmlNode newChild2 = xmlDoc.ImportNode(xmlDocument.DocumentElement, deep: true);
						xmlDoc.RemoveChild(xmlDoc.DocumentElement);
						xmlDoc.AppendChild(newChild2);
						break;
					}
					if (xPathNavigator.NodeType == XPathNodeType.Attribute)
					{
						xPathNavigator.SetValue(val);
					}
					else
					{
						if (xPathNavigator2 == null)
						{
							xmlDocFragmentInternal = xmlDoc.CreateDocumentFragment();
							xmlDocFragmentInternal.InnerXml = val;
							xPathNavigator2 = xmlDocFragmentInternal.CreateNavigator();
						}
						xPathNavigator.ReplaceSelf(xPathNavigator2);
					}
					num2--;
				}
				xPathNavigator.MoveToNext();
			}
		}

		internal static void Update(XmlDocument xmlDoc, string xpathExpr, string nsMap, string val, ref bool bValueIsFragment)
		{
			XmlNamespaceManager nsMgr = StringToNsMgr(xmlDoc.NameTable, nsMap);
			Update(xmlDoc, xpathExpr, nsMgr, val, ref bValueIsFragment);
		}

		internal static XmlDocument GetXmlDocument(XmlTypeReader xmlReader, string value, out XmlDocumentFragment xmlDocFragmentInternal, out bool bIsFragment, bool bThrowException)
		{
			XmlDocument xmlDocument = null;
			xmlDocument = new XmlDocument();
			xmlDocument.PreserveWhitespace = true;
			bIsFragment = false;
			xmlDocFragmentInternal = null;
			try
			{
				xmlDocument.Load(xmlReader);
				return xmlDocument;
			}
			catch (Exception)
			{
				if (bThrowException)
				{
					throw;
				}
				xmlDocument.LoadXml("<OracleInternalXmlRoot/>");
				xmlDocFragmentInternal = xmlDocument.CreateDocumentFragment();
				xmlDocFragmentInternal.InnerXml = value;
				xmlDocument.DocumentElement.AppendChild(xmlDocFragmentInternal);
				bIsFragment = true;
				return xmlDocument;
			}
		}

		internal static string NsMgrToString(XmlNamespaceManager nsMgr)
		{
			string result = null;
			if (nsMgr != null)
			{
				result = string.Empty;
				{
					foreach (string item in nsMgr)
					{
						string text2 = nsMgr.LookupNamespace(item);
						if ((item != null && item.Length != 0) || (text2 != null && text2.Length != 0))
						{
							StringBuilder stringBuilder = new StringBuilder(result, 1024);
							if (result != null && result.Length != 0)
							{
								stringBuilder.Append(' ');
							}
							stringBuilder.Append("xmlns:");
							stringBuilder.Append(item);
							stringBuilder.Append('=');
							stringBuilder.Append(text2);
							result = stringBuilder.ToString();
							stringBuilder = null;
						}
					}
					return result;
				}
			}
			return result;
		}

		internal static XmlNamespaceManager StringToNsMgr(XmlNameTable nameTable, string nsMap)
		{
			XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(nameTable);
			if (string.IsNullOrEmpty(nsMap))
			{
				return xmlNamespaceManager;
			}
			string s = "<Namespace1 " + nsMap + " ></Namespace1>";
			XmlDocument xmlDocument = new XmlDocument();
			XmlReader reader = XmlReader.Create(settings: new XmlReaderSettings
			{
				DtdProcessing = DtdProcessing.Ignore
			}, input: new StringReader(s));
			xmlDocument.Load(reader);
			foreach (XmlAttribute attribute in xmlDocument.DocumentElement.Attributes)
			{
				if (xmlNamespaceManager.LookupNamespace(attribute.LocalName) == null)
				{
					xmlNamespaceManager.AddNamespace(attribute.LocalName, attribute.Value);
				}
			}
			return xmlNamespaceManager;
		}
	}
}
